package cn.goour.web.dser.controller.admin

import cn.goour.utils.io.IO
import cn.goour.web.base.`interface`.ValidModifying
import cn.goour.web.base.entity.Msg
import cn.goour.web.base.entity.PageInfo
import cn.goour.web.base.exception.BackJsonBeanValidFailException
import cn.goour.web.dser.entity.SchoolIp
import cn.goour.web.dser.service.SchoolIpService
import format
import getAdmin
import getRealIp
import getUserAgent
import org.apache.commons.lang3.ArrayUtils
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.xssf.streaming.SXSSFWorkbook
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.io.ClassPathResource
import org.springframework.data.domain.Page
import org.springframework.stereotype.Controller
import org.springframework.validation.Errors
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.net.URLEncoder
import java.util.*
import java.util.UUID
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.validation.Valid
import javax.validation.groups.Default


@Controller
@RequestMapping("/admin/schoolIp")
open class AdminSchoolIpController {
    @Autowired private
    lateinit var service: SchoolIpService

    @RequestMapping("/list")
    open fun index(): String = "web/admin/schoolIp/list"

    @ResponseBody
    @RequestMapping("/list", method = arrayOf(RequestMethod.GET), headers = arrayOf("X-Requested-With"))
    open fun list(@Valid pageInfo: PageInfo, errors: Errors): Msg {
        if (errors.hasErrors()) {
            throw BackJsonBeanValidFailException(errors)
        }
        val list: Page<SchoolIp>? = service.getList(pageInfo)
        return if (list != null) {
            Msg(list)
        } else {
            Msg.error("没有记录")
        }
    }

    @ResponseBody
    @RequestMapping("/list", method = arrayOf(RequestMethod.POST), headers = arrayOf("X-Requested-With"))
    open fun add(@Valid schoolIp: SchoolIp, errors: Errors): Msg {
        if (errors.hasErrors()) {
            throw BackJsonBeanValidFailException(errors)
        }
        logger.info("添加：$schoolIp")
        service.add(schoolIp)
        return Msg()
    }

    @ResponseBody
    @RequestMapping("/list", method = arrayOf(RequestMethod.PUT), headers = arrayOf("X-Requested-With"))
    open fun update(@Validated(ValidModifying::class, Default::class) schoolIp: SchoolIp, errors: Errors): Msg {
        if (errors.hasErrors()) {
            throw BackJsonBeanValidFailException(errors)
        }
        logger.info("修改：$schoolIp")
        service.update(schoolIp)
        return Msg()
    }

    @ResponseBody
    @RequestMapping("/list", method = arrayOf(RequestMethod.DELETE), headers = arrayOf("X-Requested-With"))
    open fun del(@RequestParam("id[]") id: Array<Int>): Msg {
        service.delete(id)
        return Msg()
    }

    @ResponseBody
    @RequestMapping("/clear", method = arrayOf(RequestMethod.POST))
    open fun clear(): Msg {
        service.clear()
        return Msg()
    }

    @RequestMapping("/import")
    open fun import(): String = "web/admin/schoolIp/import"

    @ResponseBody
    @RequestMapping("/export")
    open fun export(request: HttpServletRequest, response: HttpServletResponse) {
        val list = service.findAll()
        if (list != null) {
            try {
                val no = Date().format("yyyyMMdd-HHmmss")

                val fileName = UUID.randomUUID().toString() + "(" + no + ").xlsx"

                val downloadFileName = URLEncoder.encode("鹿山内网IP地址（$no）.xlsx", "utf-8")

                // 创建保存目录
                val root = ClassPathResource("/static/").file
                val path = File(root, "download/ip/")
                if (!path.exists()) {
                    path.mkdirs()
                }
                val file = File(path, fileName)
                saveListToFile(file, list)
                response.contentType = "application/force-download"// 设置强制下载不打开
                response.addHeader("Content-Disposition", "attachment;fileName=" + downloadFileName)// 设置文件名
                val input = file.inputStream()
                val bytes = IO.read(input)
                input.close()

                response.outputStream.write(bytes)
                response.outputStream.flush()

            } catch (e: Exception) {
                e.printStackTrace()
                response.sendRedirect(request.contextPath + "/404.html")
            }
        } else {
            response.sendRedirect(request.contextPath + "/404.html")
        }
    }

    @Throws(IOException::class)
    private fun saveListToFile(file: File, list: MutableList<SchoolIp>) {
        val output = FileOutputStream(file)
        val wb = SXSSFWorkbook(list.size + 10)
        val sheet = wb.createSheet("鹿山内网IP地址表")
        val field = arrayOf("building", "room", "ip1", "ip2", "gw", "mask", "dns1", "dns2")
        val head = arrayOf("建筑标号", "房间号", "IP始地址", "IP终地址", "网关", "子网掩码", "DNS1（首选DNS）", "DNS2（备用DNS）")
        val width = intArrayOf(10, 8, 15, 15, 15, 15, 18, 18)
        // 绘制电子表格的头部信息
        val row = sheet.createRow(0)
        for (i in head.indices) {
            val cell = row.createCell(i)
            cell.setCellType(CellType.STRING)
            cell.setCellValue(head[i])
            sheet.setColumnWidth(i, width[i] * 256)
        }
        // 绘制电子表格的具体内内容信息
        var i = 1
        for (ipInfo in list) {
            val row2 = sheet.createRow(i++)
            val map = ipInfo.toMap()
            for (j in field.indices) {
                val cell = row2.createCell(j)
                cell.setCellType(CellType.STRING)
                cell.setCellValue(map[field[j]])
            }
        }
        wb.write(output)
        wb.close()
    }

    @ResponseBody
    @RequestMapping("/import", method = arrayOf(RequestMethod.POST))
    open fun importIp(@RequestParam("file") file: MultipartFile, request: HttpServletRequest): Msg {
        return try {
            if (!file.isEmpty) {
                val ext = file.originalFilename.substring(file.originalFilename.lastIndexOf(".") + 1, file.originalFilename.length).toLowerCase()
                if (ArrayUtils.contains(fileType, file.contentType) || ArrayUtils.contains(fileExt, ext)) {
                    try {

                        val admin = request.getAdmin()
                        val ip = request.getRealIp()
                        val ua = request.getUserAgent()


                        val root = ClassPathResource("/static/").file
                        val path = File(root, "/tmp/")
                        if (!path.exists()) {
                            path.mkdirs()
                        }
                        val saveFile = File(path, "${UUID.randomUUID().toString().replace("-", "")}${file.originalFilename}")
                        file.transferTo(saveFile)

                        service.saveAll(ext, saveFile, admin, ip, ua)
                        Msg("系统正在后台为您导入数据，可通过日志记录查看导入结果")
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Msg.error(e)
                    }
                } else {
                    Msg.error("上传文件格式不正确")
                }
            } else {
                Msg.error("导入用户失败，没有上传文件")
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Msg.error(e)
        }
    }

    companion object {
        private val logger = LoggerFactory.getLogger(AdminSchoolIpController::class.java)
        val fileType = arrayOf("application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
        val fileExt = arrayOf("xls", "xlsx", "csv")
    }
}